package com.API;

import com.API.Node;
import com.javacore.Manager;

import java.util.*;

/**
 * @author JSU-Coder
 * @version 1.0  (此版本有很多不足的地方，虽然方法效果实现了，但部分方法采用遍历实现，以后进行升级，折半)
 */
public class link extends List1{

    /**
     * 链表的头节点
     */
    private Node head;
    /**
     * 链表的尾节点
     */
    private Node last;
    /**
     * 链表的数组
     */
    private int size;

    /**
     * 添加节点到头结点
     * @param data 增添的数据
     */
    public void addFirst(int data){
       Node nowNode = new Node(data);
        if (size == 0 ){
            head = nowNode;
            last = nowNode;
        }
        nowNode.next = head;
        head = nowNode;
        size++;
    }

    /**
     * 添加元素到链表尾部
     * @param data 增添的数据
     * @return 布尔值
     */
    public boolean add(int data){
        //创建节点
        int flag = size;
     Node nowNode = new Node(data);
        if (head == null){
            head = nowNode;
            last = nowNode;
        }
        last.next = nowNode;
        last = nowNode;
        size ++;
        if (flag == size){
            return false;
        }else
            return true;
    }

    /**
     * 通过链表的索引和数据添加元素
     * @param data 增加的数据
     * @param index 链表的索引
     */
    public void add(int data,int index){
        if (index<0 || index > size){
            throw new IndexOutOfBoundsException("超出链表节点范围");
        }
        //创捷节点对象
        Node insertNode = new Node(data);

        if (size == 0){
            head =insertNode;
            last = insertNode;
        }
        else if (index == 0){
          insertNode.next = head;
          head = insertNode;
        }
        else if (index == size){
            last.next = insertNode;
            last = insertNode;
        }
        //插入中间
        else{
           Node temp = head;
            for (int i = 0;i<index-1;i++){
                temp = temp.next;
            }
            insertNode.next = temp.next;
            temp.next = insertNode;
            //插入成功
        }
        size++;
    }

    /**
     * 通过指定索引删除链表元素
     * @param index 链表索引
     */

    public void remove(int index){
        Node preNode = null;
        preNode = head;
        //尾部删除
        if (index == size-1){
            for (int i = 0; i<index-1; i++){
                preNode = preNode.next;
            }
            //遍历完后，temp指向链表倒数第二个
            preNode.next = null;
            last = preNode;
        }
        //删除头部
        else if (index == 0){
            head = head.next;
        }
        //删除中间元素
        else{
            for(int i = 0;i<index -1;i++){
                preNode = preNode.next;
            }
            preNode.next = preNode.next.next;
        }

    }

    /**
     * 删除链表索引为0的元素
     * @return 返回被删除的数据
     */
    public int remove(){
        if (size ==0)
            throw new IndexOutOfBoundsException("链表为空");
       final int removeData = head.data;
       Node newHeadNode = head.next;
        head = newHeadNode;
        size--;
        return removeData;
    }

    /**
     *遍历链表展示链表各元素
     */
    public void showLink() {
   Node now = head;
        for (int i = 0;i<size;i++){
            System.out.println(now.data);
            now = now.next;
        }
    }

    /**
     * 清除链表所有元素  clear
     */
    public void clear(){
        //将每一位的元素都指向为空
        for (Node nowNode = head; nowNode != null;){
            Node nodeNext = nowNode.next;
            nowNode.next = null;
            nowNode = nodeNext;
            size--;
        }

        head = null;
        last = null;
    }

    /**
     * 通过索引获取元素
     * @param index 链表索引
     * @return 链表索引节点下的数据
     * @throws IndexOutOfBoundsException 超出链表节点范围
     */
    public int get(int index){
        if (index >=size || index <0){
            throw new IndexOutOfBoundsException("超出链表节点范围");
        }

        if (size == 0){
            System.out.println("该链表为空");
            return -1;
        }
        else{
            Node nowNode = head;
            for (int i = 0;i< index -1;i++){
                nowNode = nowNode.next;
            }
            return nowNode.next.data;

        }

    }
    /**
     * 查看链表是否包含该元素
     * @param data 要判断的数据
     * @return boolean 如果包含则返回true,否则返回false。
     */
    public boolean contains(int  data){

        Node nowNode = head;
        for (int i = 0;i < size;i++){
            if (nowNode.data == data){
                return true;
            }
            nowNode = nowNode.next;
        }
        return false;
    }

    /**
     * 获取整数链表的元素数量
     * @return 链表的大小（节点数量）
     */
    public int size(){

        return size;
    }

    /**
     * 通过索引更新链表节点的数据区域
     * @param index
     * @return  被替代之前的数据
     * @param data
     * @throws IndexOutOfBoundsException 超出链表节点
     */
    public int set(int index,int data){
        if (index >=size || index < 0){
            throw new IndexOutOfBoundsException("超出链表节点范围");
        }

        Node nowNode = head;
        for (int i = 0;i<index-1;i++){
            nowNode = nowNode.next;
        }
        int preData = data;
        nowNode.next.data = data;

        return preData;
    }

    /**
     * 添加元素到链表尾部
     * @param data 添加的数据
     * @return 如果添加成功返回true,否则返回false。
     */
    public boolean offer(int data){
        return add(data);
    }

    /**
     *
     * @return 链表的头节点，如果链表为空则返回null;
     */
    public int peek(){
        return size == 0 ? null : head.data;
    }

    /**
     * 删除头节点，斌返回被删除的节点元素
     * @return 被删除的节点元素
     */
    public int pop(){
        return this.remove();
    }

    /**
     *  添加节点到头结点
     * @param data 添加的数据
      */
    public void push(int data){
        addFirst(data);
    }

    /**
     * @author luolin
     * @version 1.0
     */
     class Node {
        /**
         * 节点的数据
         */
        int data;
        /**
         * 指向下一位节点的指针
         */
        Node next;

        /**
         * 这是一个构造器
         * @param data
         */
        Node(int data){
            this.data = data;

        }
    }


//    /**
//     * 测试方法
//     *
//     * @Long time = System.currentTimeMillis();
//     *        link link = new link();
//     *
//     *        link.add(1);
//     *        link.add(3);
//     *        link.add(34);
//     *        link.set(2,5435);
//     *        link.remove();
//     *        System.out.println( link.get(0));
//     *        System.out.println(link.contains(34));
//     *        link.showLink();
//     *
//     *     输出结果如下：34
//     *                  1
//     *                  3
//     *                  5435
//     *                  false
//     *                  1
//     *                  5435
//     *
//     *
//     * @param args 命令行参数
//     *
//     */
//    public  void test(String[] args) {
//        Long time = System.currentTimeMillis();
//       link link = new link();
//       link.add(1);
//       link.add(3);
//       link.addFirst(34);
//       link.showLink();
//       link.set(2,5435);
//       link.remove();
//       System.out.println( link.get(0));
//       System.out.println(link.contains(34));
//       link.showLink();
//
//    }
    public static void main(String[] args) {

//        LinkedList<Integer> link1 = new LinkedList<>();
//
//        Runnable task1 = ()->{
//            try {
//                for(int i =0;i<100;i++){
//
//
//                link1.add(new Random().nextInt());
//                Thread.sleep(1000);
//                }
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        };
//
//        Runnable task2 = () ->{
//            try{
//                for (int i = 0;i< 100;i++)
//                {
//                    System.out.println(12);
//                    Thread.sleep(1000);
//                }
//            }catch (InterruptedException e){
//                e.printStackTrace();
//            }
//        };
//        new Thread(task1).start();
//        new Thread(task2).start();
        link a = new link();
        a.add(1);
        a.add(67);
        a.add(23);
        a.get(4);
        "sdf".hashCode();


    }


}